package com.grm.common.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Date;

/**
 * 日期/时间工具类
 *
 * @author gaorimao
 * @since 2022-06-22
 */
public class DateUtils {
    public static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";

    public static final String TIMESTAMP_FORMAT = "yyyyMMddHHmmssS";
    public static final String DATE = "yyyy-MM-dd";

    /**
     * 时间字符串转时间格式
     *
     * @param dateString 时间字符串
     * @return date
     */
    public static Date dateStringToDate(String dateString) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DATE_FORMAT);
        Date date = null;
        try {
            date = simpleDateFormat.parse(dateString);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    /**
     * 时间字符串转时间格式
     *
     * @param dateString 时间字符串
     * @param format     时间格式
     * @return date
     */
    public static Date dateStringToDate(String dateString, String format) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
        Date date = null;
        try {
            date = simpleDateFormat.parse(dateString);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    /**
     * 时间转时间字符串格式
     *
     * @param date   时间
     * @param format 时间格式
     * @return dateStr
     */
    public static String dateToDateStr(Date date, String format) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
        return simpleDateFormat.format(date);
    }

    /**
     * 时间转时间字符串格式
     *
     * @param date   时间
     * @param format 时间格式
     * @return dateStr
     */
    public static String dateToTimeStampStr(Date date, String format) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
        return simpleDateFormat.format(date);
    }

    public static Date localDateTimeToDate(LocalDateTime localDateTime) {
        return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
    }

    public static LocalDateTime dateToLocalDateTime(Date date) {
        return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
    }

    /**
     * 时间戳转时间字符串格式
     *
     * @param timestamp 时间戳
     * @param format    时间格式
     * @return dateStr
     */
    public static String timestampToDateStr(Long timestamp, String format) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
        return simpleDateFormat.format(new Date(timestamp));
    }

    /**
     * 获取当前时间点的字符串
     * @return 当前时间点的字符串
     */
    public static String getCurrentLocalDateTimeStr() {
        return dateToDateStr(DateUtils.localDateTimeToDate(LocalDateTime.now()), DateUtils.TIMESTAMP_FORMAT);
    }

    /**
     * 获取两个时间的时间差，并返回小时和分钟的字符串
     * @param startTime 开始时间字符串，格式为 "HH:mm"
     * @param endTime 结束时间字符串，格式为 "HH:mm"
     * @return 时间差的字符串表示（例如："1小时55分" 或 "30分"）
     */
    public static String getTimeDifference(String startTime, String endTime) {
        // 定义时间格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm");
        // 解析开始时间和结束时间
        LocalTime start = LocalTime.parse(startTime, formatter);
        LocalTime end = LocalTime.parse(endTime, formatter);
        // 计算时间差
        Duration duration = Duration.between(start, end);
        // 获取小时和分钟
        long hours = duration.toHours();
        long minutes = duration.toMinutesPart();
        // 构建时间差的字符串
        String result;
        if (hours > 0) {
            result = hours + "小时" + minutes + "分";
        } else {
            result = minutes + "分";
        }
        return result;
    }

    /**
     * 计算两个日期之间的天数差
     * @param startDateTime 开始日期字符串，格式为 "yyyy-MM-dd HH:mm:ss"
     * @param endDateTime 结束日期字符串，格式为 "yyyy-MM-dd HH:mm:ss"
     * @return 日期之间的天数差
     */
    public static long getDaysDifference(String startDateTime, String endDateTime) {
        // 定义日期时间格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        // 解析开始日期时间和结束日期时间
        LocalDateTime start = LocalDateTime.parse(startDateTime, formatter);
        LocalDateTime end = LocalDateTime.parse(endDateTime, formatter);

        // 计算日期时间之间的天数差
        long daysDifference = ChronoUnit.DAYS.between(start, end);
        return daysDifference;
    }

    /**
     * 计算两个日期时间之间的时间差
     * @param startTime 开始时间字符串，格式为 "yyyy-MM-dd HH:mm:ss"
     * @param endTime 结束时间字符串，格式为 "yyyy-MM-dd HH:mm:ss"
     * @return 时间差的字符串表示（例如："10天0时0分" 或 "23时59分"）
     */
    public static String getTimeDifferenceV2(String startTime, String endTime) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime start = LocalDateTime.parse(startTime, formatter);
        LocalDateTime end = LocalDateTime.parse(endTime, formatter);

        Duration duration = Duration.between(start, end);

        long days = duration.toDays();
        long hours = duration.toHours() % 24;
        long minutes = duration.toMinutes() % 60;

        StringBuilder result = new StringBuilder();
        if (days > 0) {
            result.append(days).append("天");
        }
        if (hours > 0 || days > 0) {
            result.append(hours).append("时");
        }
        result.append(minutes).append("分");

        return result.toString();
    }

    /**
     * 计算两个时间差
     */
    public static String getDatePoor(Date endDate, Date nowDate) {
        long nd = 1000 * 24 * 60 * 60;
        long nh = 1000 * 60 * 60;
        long nm = 1000 * 60;
        // long ns = 1000;
        // 获得两个时间的毫秒时间差异
        long diff = endDate.getTime() - nowDate.getTime();
        // 计算差多少天
        long day = diff / nd;
        // 计算差多少小时
        long hour = diff % nd / nh;
        // 计算差多少分钟
        long min = diff % nd % nh / nm;
        // 计算差多少秒//输出结果
        // long sec = diff % nd % nh % nm / ns;
        return day + "天" + hour + "小时" + min + "分钟";
    }

    /**
     * 比较两个日期时间的大小
     * @param beginTimeStr 开始时间字符串，格式为 "yyyy-MM-dd HH:mm:ss"
     * @param endTimeStr 结束时间字符串，格式为 "yyyy-MM-dd HH:mm:ss"
     * @return 如果 beginTimeStr < endTimeStr 返回 true，否则返回 false
     */
    public static boolean compare(String beginTimeStr, String endTimeStr) {
        // 定义日期时间格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        // 解析开始时间和结束时间
        LocalDateTime beginTime = LocalDateTime.parse(beginTimeStr, formatter);
        LocalDateTime endTime = LocalDateTime.parse(endTimeStr, formatter);

        // 比较开始时间和结束时间
        return beginTime.isBefore(endTime);
    }
}
